package edu.wichita.weighin;

import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.util.SerialInputOutputManager;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.TextView;

public class MetalsMenuActivity extends ActionBarActivity {
       
    private final String TAG = MetalsMenuActivity.class.getSimpleName();
    ExpandableListAdapter listAdapter;
    ExpandableListView expListView;
    List<String> listDataHeader;
    HashMap<String, List<String>> listDataChild;
    TextView metalChosen;
    String metal;
    TextView showWeight;
    Button buttonTare;
    float asFloat = 0;
    String weightFileName = "storedweights";
    FileOutputStream outputStream = null;
    float tareValue = 0;

    private static UsbSerialDriver sDriver = null;
    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
    private SerialInputOutputManager mSerialIoManager;
    private final SerialInputOutputManager.Listener mListener = 
            new SerialInputOutputManager.Listener() {

        @Override
        public void onRunError(Exception e) {
            Log.d(TAG, "Runner stopped.");
        }

        @Override
        public void onNewData(final byte[] data) {
            MetalsMenuActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    MetalsMenuActivity.this.updateReceivedData(data);
                }
            });
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_metals_menu);
               
        buttonTare = (Button) findViewById(R.id.button_tare);
        buttonTare.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                tareValue = asFloat; 
                SaveWeightDialogFragment newFragment = SaveWeightDialogFragment.newInstance(asFloat);
                newFragment.show(getSupportFragmentManager(), "weight");
            }
        });
               
        metalChosen = (TextView) findViewById(R.id.metal_chosen);
        metal = "none";
        metalChosen.setText("Metal Chosen: " + metal);
               
        // get the ListView
        expListView = (ExpandableListView) findViewById(R.id.expandableListView_metals);
        // preparing list data
        prepareListData("Choose a Metal");

        listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);

        // setting list adapter
        expListView.setAdapter(listAdapter);
               
        // ListView Group click listener
        expListView.setOnGroupClickListener(new OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v,
                    int groupPosition, long id) {
                // Toast.makeText(getApplicationContext(),
                // "Group Clicked " + listDataHeader.get(groupPosition),
                // Toast.LENGTH_SHORT).show();
                return false;
            }
        });

        // ListView Group expanded listener
        expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupPosition) {
                //Toast.makeText(getApplicationContext(),
                //listDataHeader.get(groupPosition) + " Expanded",
                //Toast.LENGTH_SHORT).show();
            }
        });

        // ListView Group collapsed listener
        expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
            @Override
            public void onGroupCollapse(int groupPosition) {
                //Toast.makeText(getApplicationContext(),
                //listDataHeader.get(groupPosition) + " Collapsed",
                //Toast.LENGTH_SHORT).show();
            }
        });

        // ListView on child click listener
        expListView.setOnChildClickListener(new OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                    int groupPosition, int childPosition, long id) {
                    
                if(parent.isGroupExpanded(groupPosition)) {
                    parent.collapseGroup(groupPosition);
                }
                metal = listDataChild.get(listDataHeader.get(groupPosition)).get(childPosition);
                metalChosen.setText("Metal Chosen: " + metal);
                return false;
            }
        });
        
        showWeight = (TextView) findViewById(R.id.show_weight);
        showWeight.setText(">> Weight will appear here <<");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.metals_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    private void prepareListData(String header) {
               
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();

        // Adding child data
        listDataHeader.add(header);

        // Adding child data
        List<String> listOfMetals = new ArrayList<String>();
        listOfMetals.add("GOLD 24K");
        listOfMetals.add("GOLD 23K");
        listOfMetals.add("GOLD 22K");
        listOfMetals.add("GOLD 18K");
        listOfMetals.add("GOLD 14K");
        listOfMetals.add("SILVER");
        listOfMetals.add("PLATINUM");

        listDataChild.put(listDataHeader.get(0), listOfMetals); // Header, Child data
        
    }
    
    public void passMetal(View view) {
        new PriceFetch(getApplicationContext()).pickData(metal, asFloat);
    }
    
    @Override
    protected void onPause() {
       
        super.onPause();
        stopIoManager();
        if (sDriver != null) {
            try {
                sDriver.close();
            } catch (IOException e) {
                // Ignore.
            }
            sDriver = null;
        }
        finish();
    }

    @Override
    protected void onResume() {
       
        super.onResume();
        Log.d(TAG, "Resumed, sDriver=" + sDriver);
        if (sDriver == null) {
            //showDialogueNoDeviceFound.show(getSupportFragmentManager(), "nodevice");
            //this.finish();
        } else {
            try {
                sDriver.open();
                sDriver.setParameters(19200, 8, UsbSerialDriver.STOPBITS_1, UsbSerialDriver.PARITY_NONE);
            } catch (IOException e) {
                Log.e(TAG, "Error setting up device: " + e.getMessage(), e);
                try {
                    sDriver.close();
                } catch (IOException e2) {
                    // Ignore.
                }
                sDriver = null;
                return;
            }
        }
        onDeviceStateChange();
       
    }

    private void stopIoManager() {
       
        if (mSerialIoManager != null) {
            Log.i(TAG, "Stopping io manager ..");
            mSerialIoManager.stop();
            mSerialIoManager = null;
        }
    }

    private void startIoManager() {
       
        if (sDriver != null) {
            Log.i(TAG, "Starting io manager ..");
            mSerialIoManager = new SerialInputOutputManager(sDriver, mListener);
            mExecutor.submit(mSerialIoManager);
        }
    }

    private void onDeviceStateChange() {
        stopIoManager();
        startIoManager();
    }

    private void updateReceivedData(byte[] data) {
       
        int MASK = 0xFF;
        int bits = 0;
        int i = 0;
        for(int shifter = 0; shifter < data.length; shifter++) {
            bits |= (data[i] & MASK) << (shifter * 8);
            i++;
        }
        asFloat = Float.intBitsToFloat(bits);
        DecimalFormat df = new DecimalFormat("####.#");

        if (data.length == 4)
        {
        
        final String message = "Weight " + data.length + " bytes: \n"
                + (df.format(asFloat - tareValue)) + "\n\n";
        showWeight.setText(message);
        }
    }

    /**
     * Starts the activity, using the supplied driver instance.
     *
     * @param context
     * @param driver
     */
    static void show(Context context, UsbSerialDriver driver) {
       
        sDriver = driver;
        final Intent intent = new Intent(context, MetalsMenuActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
        context.startActivity(intent);
    }

}